package com.example.jrfwcwgl.controller;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.jrfwcwgl.entity.PaymentPlan;
import com.example.jrfwcwgl.service.AlibabaPayService;
import com.example.jrfwcwgl.service.IPaymentPlanService;
import com.groupone.aliPay.alibaba.qrcode.config.AliQrPayConfig;
import com.groupone.aliPay.alibaba.qrcode.service.AlibabapayQrCodeService;

import com.org.vo.ResultEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/jrfwcwgl/payPlan")
@Slf4j
public class AlibabaPayController {

    @Autowired
    AlibabapayQrCodeService alibabapayQrCodeService;

    @Autowired
    AlibabaPayService alibabaPayService;


//    @Bean
 //   public TUser tUser(){
//        TUser tUser = new TUser(tRole());
//        //tUser.setRole(tRole());
//        return tUser;
//    }
//
//    @Bean
//    public TRole tRole(){
//        return new TRole();
//    }

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    @Autowired
    private IPaymentPlanService paymentPlanService;

    @RequestMapping("/createPayOrder")
    public ResultEntity createPayOrder(String id) throws AlipayApiException {
        //通过id去查询支付计划
        PaymentPlan byId = paymentPlanService.getById(id);

        log.info("创建支付宝扫码订单开始订单号为:{}",byId);
        String key = "payMent:pay_"+byId.getId();
        if(redisTemplate.hasKey(key)){
            String qrcode = redisTemplate.opsForValue().get(key);
            log.info("根据支付计划id:{}到redis 中查询二维码:{}",byId.getId(),qrcode);
            return ResultEntity.ok("创建支付宝扫码支付订单成功",qrcode);
        }
        log.info("根据orderNo:{}到redis 中查询二维码不存在开始调用支付宝的接口创建预支付订单......");
        Map<String,String> map = new HashMap<>();
        map.put("out_trade_no",byId.getId()+"");
        map.put("trade_no",byId.getContractNo());
        map.put("total_amount",byId.getPaymentAmount()+"");
        map.put("subject","第"+byId.getPayNumber()+"期账单");
        //商家id
        map.put("store_id","2021000118654679");
        map.put("timeout_express","7200m");
        AlipayTradePrecreateResponse qrCodePayOrder = alibabapayQrCodeService.createQrCodePayOrder(map);
        String qrcode = alibabaPayService.getAlibabaPayQRCode(qrCodePayOrder);
        log.info("创建支付宝扫码订单结束订单号为:{}",byId.getId());
        return ResultEntity.ok("创建支付宝扫码支付订单成功",qrcode);
    }

    @RequestMapping("backInfo")
    public void backInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("此方法为即将废弃的方法，请使用  新方法");
        log.info("支付宝扫码支付回调开始:..................");
        log.debug("通知时间:{}",request.getParameter("notify_time"));
        log.debug("通知类型:{}",request.getParameter("notify_type"));
        log.debug("通知校验ID:{}",request.getParameter("notify_id"));
        log.debug("签名类型:{}",request.getParameter("sign_type"));
        log.debug("签名:{}",request.getParameter("sign"));
        log.debug("支付宝交易号:{}",request.getParameter("trade_no"));
        log.debug("开发者的app_id:{}",request.getParameter("app_id"));
        log.debug("商户订单号:{}",request.getParameter("out_trade_no"));
        log.debug("商户业务号:{}",request.getParameter("out_biz_no"));
        log.debug("买家支付宝用户号:{}",request.getParameter("buyer_id"));
        log.debug("买家支付宝账号:{}",request.getParameter("buyer_logon_id"));
        log.debug("卖家支付宝用户号:{}",request.getParameter("seller_id"));
        log.debug("卖家支付宝账号:{}",request.getParameter("seller_email"));
        log.debug("交易状态:{}",request.getParameter("trade_status"));
        log.debug("订单金额:{}",request.getParameter("total_amount"));
        log.debug("实收金额:{}",request.getParameter("receipt_amount"));
        log.debug("开票金额:{}",request.getParameter("invoice_amount"));
        log.debug("付款金额:{}",request.getParameter("buyer_pay_amount"));
        log.debug("集分宝金额:{}",request.getParameter("point_amount"));
        log.debug("总退款金额:{}",request.getParameter("refund_fee"));
        log.debug("实际退款金额:{}",request.getParameter("send_back_fee"));
        log.debug("订单标题:{}",request.getParameter("subject"));
        log.debug("通知时间:{}",request.getParameter("notify_time"));
        log.debug("商品描述:{}",request.getParameter("body"));
        log.debug("交易创建时间:{}",request.getParameter("gmt_create"));
        log.debug("交易付款时间:{}",request.getParameter("gmt_payment"));
        log.debug("交易退款时间:{}",request.getParameter("gmt_refund"));
        log.debug("交易结束时间:{}",request.getParameter("gmt_close"));
        log.debug("支付金额信息:{}",request.getParameter("fund_bill_list"));


        //遍历map的第四种方式  直接遍历Set
        Map<String,String> params = new HashMap<>();
        for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
            params.put(entry.getKey(),entry.getValue()[0]);
        }
        log.info("支付宝返回的参数重新组装成map内容为:{}", JSON.toJSONString(params));
        try {
            //校验阶段
            //1  数字签名校验 安全  作用是此次请求是不是支付宝的请求,请求参数有没有被篡改
            /**
             @param params 参数列表(包括待验签参数和签名值sign) key-参数名称 value-参数值
             @param publicKey 验签公钥
             @param charset 验签字符集  MD5(（notify_time=1&total_amount=2&notify_time=1))
             **/
            boolean result = AlipaySignature.rsaCertCheckV1(params, AliQrPayConfig.alipayCertPath, "UTF-8","RSA2");
            if (result){
                log.info("验签成功.......");
                Integer out_trade_no = Integer.parseInt(params.get("out_trade_no"));
                //2  判断订单号是否存在  订单号如果不存在 打印日志  return
                if (out_trade_no == null){
                    log.info("订单号不存在");
                    return;
                }
                //查询订单
                PaymentPlan plan = paymentPlanService.getById(out_trade_no);
                //3  判断订单状态是不是未支付或者部分支付  如果不是这两种状态 打印日志 return
                if (plan.getPayState() != 1){
                    log.info("订单状态异常");
                    return;
                }
                //4  支付宝返回的金额和数据库中的金额是否一致 如果不一致 打印日志  return
                BigDecimal bigDecimal = new BigDecimal(params.get("receipt_amount"));
                if (!bigDecimal.equals(plan.getPaymentAmount())){
                    log.info("金额不一致");
                    return;
                }
                //校验完成  处理业务逻辑
                UpdateWrapper<PaymentPlan> paymentPlanUpdateWrapper = new UpdateWrapper<>();
                paymentPlanUpdateWrapper.set("pay_state",2);
                paymentPlanUpdateWrapper.set("update_time", new Date());
                paymentPlanUpdateWrapper.set("paid_time",new Date());
                paymentPlanUpdateWrapper.eq("id",plan.getId());
                paymentPlanService.update(paymentPlanUpdateWrapper);
            }
            if (!result){
                log.info("验签失败.......");
                return;
            }

        }catch (Exception ex){
            ex.printStackTrace();
            log.error("支付宝扫码支付回调出现异常,订单号为{}",request.getParameter("trade_no"));
            response.getWriter().write("error");
            return;
        }
        response.getWriter().write("success");
        log.info("支付宝扫码支付回调结束:..................");
    }

    @RequestMapping("checkState")
    public ResultEntity checkState(Integer id) throws InterruptedException {
        PaymentPlan byId = paymentPlanService.getById(id);
        if (byId.getPayState() == 1){
            return ResultEntity.error();
        }
        return ResultEntity.ok();
    }
}
